package br.com.equus.bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;

import br.com.arquitetura.bean.BaseBean;
import br.com.arquitetura.excecao.ExcecaoUtil;
import br.com.arquitetura.util.ComboUtil;
import br.com.arquitetura.util.ConstantesARQ;
import br.com.arquitetura.util.FacesMessagesUtil;
import br.com.arquitetura.util.Mascara;
import br.com.equus.entidade.Animal;
import br.com.equus.entidade.ManejoAnimal;
import br.com.equus.entidade.ManejoProduto;
import br.com.equus.entidade.Produto;
import br.com.equus.entidade.TipoTarefa;
import br.com.equus.entidade.UnidadeMedida;
import br.com.equus.entidade.Usuario;
import br.com.equus.service.ManejoService;
import br.com.equus.service.UsuarioService;
import br.com.equus.util.Constantes;
import br.com.equus.util.ValidacaoUtil;

@ManagedBean(name = "manejoBean")
@ViewScoped
public class ManejoBean extends BaseBean<ManejoAnimal> {

	private static final long serialVersionUID = 1L;

	@ManagedProperty(value = "#{usuarioService}")
	protected UsuarioService usuarioService;

	@ManagedProperty(value = "#{manejoService}")
	protected ManejoService manejoService;

	private List<Animal> animais;
	private List<SelectItem> listaTipoTarefa;
	private List<SelectItem> listaTipoMedida;

	private Usuario executor;
	private Usuario avaliador;
	private Integer idTipoTarefa;
	private Integer idTipoMedida;
	private Produto produto;
	private ManejoProduto manejoProduto;
	private ManejoProduto manejoProdutoExcluir;

	public ManejoBean() {
		animais = new ArrayList<Animal>();
		manejoProduto = new ManejoProduto();
		manejoProdutoExcluir = new ManejoProduto();
	}

	@SuppressWarnings("unchecked")
	@PostConstruct
	public void carregarListas() {
		try {
			Boolean save = (Boolean) getSessionMap().remove("saveManejo");
			if (save != null && save) {
				FacesMessagesUtil.addInfoMessage(this.getQualifiedName(), this.getSaveMessage() + " " + ConstantesARQ.COM_SUCESSO);
			}
			listaTipoTarefa = ComboUtil.getItens(universalManager.listBy(new TipoTarefa(true)));
			Collections.sort(listaTipoTarefa, new Comparator<SelectItem>() {
				@Override
				public int compare(SelectItem o1, SelectItem o2) {
					return o1.getLabel().compareTo(o2.getLabel());
				}
			});
			listaTipoMedida = ComboUtil.getItens(universalManager.listBy(new UnidadeMedida(true)));
			Collections.sort(listaTipoMedida, new Comparator<SelectItem>() {
				@Override
				public int compare(SelectItem o1, SelectItem o2) {
					return o1.getLabel().compareTo(o2.getLabel());
				}
			});

		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}

	}

	@SuppressWarnings("unchecked")
	@Override
	public String save() {
		try {

			if (getModel().getDtFim().before(getModel().getDtInicio())) {
				FacesMessagesUtil.addErrorMessage("Data de Término ", " Não pode ser anterior a data de Início");
				return ERROR;
			}
			getModel().setUsuarioExecutor(executor);
			getModel().setUsuarioAvaliador(avaliador);
			getModel().setTipoTarefa(new TipoTarefa(idTipoTarefa));

			List<ManejoAnimal> listaManejo = new ArrayList<ManejoAnimal>();
			for (Animal animal : animais) {
				ManejoAnimal manejo = (ManejoAnimal) getModel().clone();
				manejo.setAnimal(new Animal(animal.getId()));
				listaManejo.add(manejo);
			}

			manejoService.salvarManejo(listaManejo);
			getSessionMap().put("saveManejo", true);

		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}

		return redirect("manejo.jsf");
	}

	public void adicionarProduto() {
		try {
			if (produto == null || produto.getId() == null) {
				FacesMessagesUtil.addErrorMessage("Produto ", Constantes.CAMPO_OBRIGATORIO);
				return;
			}
			if (idTipoMedida == null || idTipoMedida.equals(0)) {
				FacesMessagesUtil.addErrorMessage("Unidade de medida ", Constantes.CAMPO_OBRIGATORIO);
				return;
			}
			if (manejoProduto == null || manejoProduto.getQtdUsoToString() == null || manejoProduto.getQtdUsoToString().equals(0)) {
				FacesMessagesUtil.addErrorMessage("Quantidade ", Constantes.CAMPO_OBRIGATORIO);
				return;
			}

			if (ValidacaoUtil.doubleValido(manejoProduto.getQtdUsoToString())) {
				manejoProduto.setQtdUso(Mascara.marcarDouble(manejoProduto.getQtdUsoToString()));
			} else {
				FacesMessagesUtil.addErrorMessage("Quantidade ", " Está em um formato incorreto");
				return;
			}
			manejoProduto.setUnidadeMedida((UnidadeMedida) universalManager.get(UnidadeMedida.class, idTipoMedida));
			manejoProduto.setProduto((Produto) universalManager.get(Produto.class, produto.getId()));
			manejoProduto.setManejoAnimal(getModel());

			getModel().getManejoProdutos().remove(manejoProduto);
			getModel().getManejoProdutos().add(manejoProduto);

			manejoProduto = new ManejoProduto();
			produto = new Produto();
			idTipoMedida = null;

		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}
	}

	public void excluirProduto() {
		if (manejoProdutoExcluir != null && manejoProdutoExcluir.getId() != null) {
			getModel().getManejoProdutosExcluir().add(manejoProdutoExcluir);
		}
		getModel().getManejoProdutos().remove(manejoProdutoExcluir);
	}

	public void loadProdutos() {
		try {
			idTipoMedida = manejoProduto.getUnidadeMedida().getId();
			produto = manejoProduto.getProduto();
			manejoProduto.setQtdUsoToString(manejoProduto.getQtdUso().toString());
		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Animal> completeAnimal(String query) {
		List<Animal> sugestoes = new ArrayList<Animal>();
		Animal a = new Animal();
		a.setNome(query);
		try {
			sugestoes = this.universalManager.listBy(a, true);
		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}
		return sugestoes;
	}

	@SuppressWarnings("unchecked")
	public List<Produto> completeProduto(String query) {
		List<Produto> sugestoes = new ArrayList<Produto>();
		Produto a = new Produto();
		a.setDescricao(query);
		try {
			sugestoes = this.manejoService.carregaProdutosPNome(query);
		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}
		return sugestoes;
	}

	public List<Usuario> completeUsuario(String query) {
		List<Usuario> sugestoes = new ArrayList<Usuario>();
		Usuario a = new Usuario();
		a.setNome(query);
		try {
			sugestoes = usuarioService.completeUsuarioAtivo(a);
		} catch (Exception e) {
			ExcecaoUtil.tratarExcecao(e);
		}
		return sugestoes;
	}

	@Override
	public void verificarAcesso() {
		acessoBean.bloquearTela("ROLE_MANEJO");

	}

	@Override
	public ManejoAnimal createModel() {
		return new ManejoAnimal();
	}

	@Override
	public String getQualifiedName() {
		return "Manejo";
	}

	@Override
	public boolean isFeminino() {
		return false;
	}

	public List<Animal> getAnimais() {
		return animais;
	}

	public void setAnimais(List<Animal> animais) {
		this.animais = animais;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public Usuario getExecutor() {
		return executor;
	}

	public void setExecutor(Usuario executor) {
		this.executor = executor;
	}

	public List<SelectItem> getListaTipoTarefa() {
		return listaTipoTarefa;
	}

	public void setListaTipoTarefa(List<SelectItem> listaTipoTarefa) {
		this.listaTipoTarefa = listaTipoTarefa;
	}

	public UsuarioService getUsuarioService() {
		return usuarioService;
	}

	public void setUsuarioService(UsuarioService usuarioService) {
		this.usuarioService = usuarioService;
	}

	public Integer getIdTipoTarefa() {
		return idTipoTarefa;
	}

	public void setIdTipoTarefa(Integer idTipoTarefa) {
		this.idTipoTarefa = idTipoTarefa;
	}

	public Produto getProduto() {
		return produto;
	}

	public void setProduto(Produto produto) {
		this.produto = produto;
	}

	public ManejoProduto getManejoProduto() {
		return manejoProduto;
	}

	public void setManejoProduto(ManejoProduto manejoProduto) {
		this.manejoProduto = manejoProduto;
	}

	public List<SelectItem> getListaTipoMedida() {
		return listaTipoMedida;
	}

	public void setListaTipoMedida(List<SelectItem> listaTipoMedida) {
		this.listaTipoMedida = listaTipoMedida;
	}

	public Integer getIdTipoMedida() {
		return idTipoMedida;
	}

	public void setIdTipoMedida(Integer idTipoMedida) {
		this.idTipoMedida = idTipoMedida;
	}

	public ManejoProduto getManejoProdutoExcluir() {
		return manejoProdutoExcluir;
	}

	public void setManejoProdutoExcluir(ManejoProduto manejoProdutoExcluir) {
		this.manejoProdutoExcluir = manejoProdutoExcluir;
	}

	public ManejoService getManejoService() {
		return manejoService;
	}

	public void setManejoService(ManejoService manejoService) {
		this.manejoService = manejoService;
	}

	public Usuario getAvaliador() {
		return avaliador;
	}

	public void setAvaliador(Usuario avaliador) {
		this.avaliador = avaliador;
	}

}
